import { createRouter, createWebHashHistory } from "vue-router";
import { generalRecursion } from "@/utils/function";
import type {
  Router,
  RouteLocationNormalized,
  RouteRecordNormalized,
  RouteMeta,
  RouteRecordRaw,
} from "vue-router";
import { isUrl } from "@/utils/validate";
import { omit, cloneDeep } from "lodash-es";
const modules = import.meta.glob("../views/**/*.{vue,tsx}");
export const Layout = () => import("@/Layout/Layout.vue");
export const BeCurrent = () => import("@/views/BeCurrent.vue");

export const getRawRoute = (
  route: RouteLocationNormalized
): RouteLocationNormalized => {
  if (!route) return route;
  const { matched, ...opt } = route;
  return {
    ...opt,
    matched: (matched
      ? matched.map((item) => ({
          meta: item.meta,
          name: item.name,
          path: item.path,
        }))
      : undefined) as RouteRecordNormalized[],
  };
};

export const pathResolve = (parentPath: string, path: string) => {
  if (isUrl(path)) return path;
  if (!parentPath) return path.startsWith("/") || !path ? path : `/${path}`;
  const childPath = path.startsWith("/") || !path ? path : `/${path}`;
  return `${parentPath}${childPath}`.replace(/\/\//g, "/");
};

// 路由降级
export const flatMultiLevelRoutes = (routes: AppRouteRecordRaw[]) => {
  const modules: AppRouteRecordRaw[] = cloneDeep(routes);
  for (let index = 0; index < modules.length; index++) {
    const route = modules[index];
    if (!isMultipleRoute(route)) {
      continue;
    }

    promoteRouteLevel(route);
  }
  return modules;
};

// 层级是否大于2
const isMultipleRoute = (route: AppRouteRecordRaw) => {
  if (!route || !Reflect.has(route, "children") || !route.children?.length) {
    return false;
  }
  const children = route.children;
  let flag = false;
  for (let index = 0; index < children.length; index++) {
    const child = children[index];
    if (child.children?.length) {
      flag = true;
      break;
    }
  }
  return flag;
};
// 生成二级路由
const promoteRouteLevel = (route: AppRouteRecordRaw) => {
  let router: Router | null = createRouter({
    routes: [route as RouteRecordRaw],
    history: createWebHashHistory(),
  });
  const routes = router.getRoutes();
  addToChildren(routes, route.children || [], route);
  router = null;
  route.children = route.children?.map((item) => omit(item, "children"));
};
// 添加所有子菜单
const addToChildren = (
  routes: RouteRecordNormalized[],
  children: AppRouteRecordRaw[],
  routeModule: AppRouteRecordRaw
) => {
  for (let index = 0; index < children.length; index++) {
    const child = children[index];
    const route = routes.find((item) => item.name === child.name);
    if (!route) {
      continue;
    }
    routeModule.children = routeModule.children || [];
    if (!routeModule.children.find((item) => item.name === route.name)) {
      routeModule.children?.push(route as unknown as AppRouteRecordRaw);
    }
    if (child.children?.length) {
      addToChildren(routes, child.children, routeModule);
    }
  }
};
// 动态生成路由
const generateRoutesFn = (
  arr: AppCustomRouteRecordRaw[]
): AppRouteRecordRaw[] => {
  const routeConfig: AppRouteRecordRaw[] = [];
  arr.forEach((item) => {
    let {
      name,
      icon,
      path,
      component,
      children,
      redirect,
      title,
      affix,
      ...arg
    } = item;
    const data: AppRouteRecordRaw = {
      path,
      component,
      meta: { title, icon, affix, ...arg },
      name,
    };
    if (redirect) {
      data.redirect = /^\//.test(redirect) ? redirect : "/" + redirect;
    }
    // if (component) {
    //   const comModule =
    //     modules[`../views/${component}.vue`] ||
    //     modules[`../views/${component}.tsx`];
    //   if (!comModule && !component.includes("#")) {
    //     console.error(
    //       `未找到${component}.vue文件或${component}.tsx文件，请创建`
    //     );
    //     data.component = BeCurrent;
    //   } else {
    //     // 动态加载路由文件，可根据实际情况进行自定义逻辑
    //     // 这里格外注意，路径二级是不加全路径得，由1级拼接，所以需要判断1级是否前面有/ ,没有就加一个
    //     if (component === "#") {
    //       data.path = /^\//.test(path) ? path : "/" + path;
    //       data.component = Layout;
    //     } else {
    //       data.component = comModule;
    //     }
    //   }
    // }
    if (children) {
      data.children = generateRoutesFn(children);
    }
    routeConfig.push(data as AppRouteRecordRaw);
  });

  return routeConfig;
};
// 根据后端返回生成路由
export const promoteRoute = (menuList: MenuBack[]): AppRouteRecordRaw[] => {
  // 平级生成多级菜单
  const cascaderList = generalRecursion(
    menuList,
    ""
  ) as unknown as AppCustomRouteRecordRaw[];
  console.log(cascaderList);

  const arr = generateRoutesFn(cascaderList);
  const verifyArr = verifyRoute(arr); // 验证下路由是否存在，若不存在，则添加默认路由

  return verifyArr;
};

/**
 * 处理异步路由，还原成路由
 * @param str
 * @returns
 */
const getRouterUrl = (str: Function): string => {
  const input = str.toString();

  const pattern = /\((.*?)\)/g;
  const match = input.match(pattern);

  if (!match || match.length == 0) return "";
  const arr = match[match.length - 1].replace(/['"()]/g, "").split("?");
  return arr[0]
    .replace("/src/", "")
    .replace(/^views\//, "")
    .replace(".vue", "")
    .replace(".tsx", "");
};

/**
 * 验证路由是否存在，如果不需要则不用执行此方法，而且异步路由判断方法亦感觉不完善
 * @param router
 * @returns
 */
export const verifyRoute = (
  router: AppRouteRecordRaw[]
): AppRouteRecordRaw[] => {
  return router.map((data) => {
    let { component, path, children } = data;
    if (component) {
      // 这里如果是异步路由 ()=> 则需要特殊处理
      if (typeof component === "function") {
        component = getRouterUrl(component);
      }
      if (!component.includes("Layout")) {
        const comModule =
          modules[`../views/${component}.vue`] ||
          modules[`../views/${component}.tsx`];
        console.log(comModule);
        if (!comModule && !component.includes("#")) {
          console.error(
            `未找到${component}.vue文件或${component}.tsx文件，请创建`
          );
          data.component = BeCurrent;
        } else {
          // 动态加载路由文件，可根据实际情况进行自定义逻辑
          // 这里格外注意，路径二级是不加全路径得，由1级拼接，所以需要判断1级是否前面有/ ,没有就加一个
          if (component === "#") {
            data.path = /^\//.test(path) ? path : "/" + path;
            data.component = Layout;
          } else {
            data.component = comModule;
          }
        }
      }
    }
    if (children) {
      data.children = verifyRoute(children);
    }
    return data;
  });
};
